﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using Lucene.Net.Search;
using SearchEngine;
using System.Windows.Forms;

namespace LuceneHelper
{
    public class DocumentsHelper:ISearchEngineDocuments,IDisposable
    {
        public DocumentsHelper(Exception[] errors, MultiSearcher searcher, TopDocs topDocsobject, SortedList<string, string> displayFieldsDictionary, string preparedSearchStatement, DateTime startTime, DateTime endTime)
        {
            this.errors = errors;
            this.topDocsobject = topDocsobject;
            this.searcher = searcher;
            this.displayFieldsDictionary = displayFieldsDictionary;
            this.preparedSearchStatement = preparedSearchStatement;
            this.startTime = startTime;
            this.endTime = endTime;
        }


        private TopDocs topDocsobject = null;
        public TopDocs TopDocsobject
        {
            get { return topDocsobject; }
        }


        private MultiSearcher searcher = null;
        public MultiSearcher Searcher
        {
            get { return searcher; }
            set { searcher = value; }
        }


        Exception [] errors=null;
        public Exception[] Errors
        {
          get { return errors; }
        }

        private SortedList<string, string> displayFieldsDictionary = new SortedList<string, string>();


        private string preparedSearchStatement = "";
        public string PreparedSearchStatement
        {
            get { return preparedSearchStatement; }
        }


        //get count
        public int Count
        {
            get
            {
                int count = 0;
                if (this.topDocsobject != null)
                {
                    count = topDocsobject.scoreDocs.Length;
                }
                return count;
            }
        }


        private DateTime startTime;
        public DateTime StartTime
        {
            get { return startTime; }
        }
        
        private DateTime endTime;
        public DateTime EndTime
        {
            get { return endTime; }
        }

        public TimeSpan SearchTime
        {
            get
            {
                return endTime - startTime;
            }
        }

        
        //get field at specified row
        public string this[int RowNumber,string FieldName]
        {
            get
            {
                string m = "";
                if (this.topDocsobject != null)
                {
                    int documentID = this.topDocsobject.scoreDocs[RowNumber].doc;
                    m = this.searcher.Doc(documentID).Get(normalizeField(FieldName));
                    if(m==null)
                    {
                        m="";
                    }
                }
                return m.Trim();
            }
        }

        //normalize fieldName
        private string normalizeField(string fieldName)
        {
            string f = fieldName;
            try
            {
                f = this.displayFieldsDictionary[fieldName.ToLower()];
            }
            catch
            {
            }
            return f;
        }


        public DataTable ExtractDataTable(int start, int end, params string[] fields)
        {
            DataTable dt = new DataTable();
            if (this.topDocsobject != null && start < this.Count && end < this.Count)
            {
                List<string> totalFields = new List<string>();
                if (fields != null && fields.Length > 0)
                {
                    for (int i = 0; i < fields.Length; i++)
                    {
                        if (!totalFields.Contains(fields[i].ToLower()))
                        {
                            totalFields.Add(fields[i].ToLower());
                        }
                    }
                }
                else
                {
                    foreach (KeyValuePair<string, string> kv in this.displayFieldsDictionary)
                    {
                        if (!totalFields.Contains(kv.Key))
                        {
                            totalFields.Add(kv.Key);
                        }
                    }
                }
                for (int i = start; i < end + 1; i++)
                {
                    DataRow dr = dt.NewRow();
                    for (int j = 0; j < totalFields.Count; j++)
                    {
                        String fieldName = totalFields[j];
                        if (!dt.Columns.Contains(fieldName))
                        {
                            dt.Columns.Add(normalizeField(fieldName));
                        }
                        string value = this[i, fieldName];
                        dr[fieldName] = value;
                    }
                    dt.Rows.Add(dr);
                }

            }
            return dt;
        }
        //===================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================--



        #region IDisposable Members

        public void Dispose()
        {
            this.searcher.Close();
        }

        #endregion
    }
}
